import { _decorator, Color, Component, EventTouch, Node, Prefab, tween, v3, Vec2, Vec3 } from 'cc';
import { PoolManager } from './PoolManager';
import { DrawingArc } from './DrawingArc';
import { BlackHoleItem } from './BlackHoleItem';
import { EventManager, MyEvent } from './EventManager';
import { BlackHole } from './BlackHole';
const { ccclass, property } = _decorator;

@ccclass('BlackHoleManager')
export class BlackHoleManager extends Component {

    public static Instance: BlackHoleManager = null;

    @property(Prefab)
    ArcPrefab: Prefab = null;

    @property(Prefab)
    ItemPrefab: Prefab = null;

    @property(Node)
    BlackHole: Node = null;

    @property(Node)
    InitPos1: Node = null;

    @property(Node)
    InitPos2: Node = null;

    @property
    MaxArcCount: number = 1000;

    @property
    CircleRadius: number = 500;

    @property
    Width: number = 10;

    @property
    Angle: number = 5;

    @property
    MaxItemCount = 1000;

    @property
    Dis = 10;

    @property
    SuctionConstant = 1000;

    @property(Node)
    AredNode: Node = null;

    @property(Node)
    StartNode: Node = null;

    public IsStart: boolean = false;
    public CententPos: Vec3 = new Vec3();
    private _curArcCount: number = 0;
    private _curItemCount: number = 0;
    private _arcs: Node[] = [];
    private _pos: Vec3[] = [];
    private _isPause: boolean = false;
    private _touchStart: Vec2 = new Vec2();

    protected onLoad(): void {
        BlackHoleManager.Instance = this;

        PoolManager.Instance.preload(this.ArcPrefab, this.MaxArcCount);
        PoolManager.Instance.preload(this.ItemPrefab, this.MaxItemCount);

        this.AredNode.once(Node.EventType.TOUCH_START, this.onTouchStart, this);
        this.AredNode.once(Node.EventType.TOUCH_END, this.onTouchEnd, this);
        this.AredNode.once(Node.EventType.TOUCH_CANCEL, this.onTouchEnd, this);
        tween(this.StartNode)
            .to(1, { scale: v3(1.2, 1.2, 1.2) }, { easing: `sineIn` })
            .to(1, { scale: v3(1, 1, 1) }, { easing: `sineIn` })
            .union()
            .repeatForever()
            .start();
    }

    protected start(): void {
        this.CententPos = this.node.getWorldPosition().clone();
        this.createItem(this.InitPos1.getWorldPosition());
        this.createItem(this.InitPos2.getWorldPosition());
    }

    protected update(dt: number): void {
        if (this._isPause) return;
        if (this._pos.length > 0) {
            this.createItem(this._pos.shift());
        }
    }

    addItem(targetPos: Vec3) {
        if (this._curItemCount > this.MaxItemCount) return;
        this._curItemCount++;
        console.error(this._curItemCount);

        this._pos.push(targetPos);
    }

    createItem(pos: Vec3) {
        const item: Node = PoolManager.Instance.get(this.ItemPrefab);
        item.getComponent(BlackHoleItem).init(this.node, pos, this.Dis, this.SuctionConstant)
    }

    removeItem(target: Node) {
        this._curItemCount--;
        PoolManager.Instance.put(target);
    }

    addArc(color: Color, vector: Vec2) {
        var arc: Node = null;
        if (this._curArcCount >= this.MaxArcCount) {
            arc = this._arcs.shift();
        } else {
            this._curArcCount++;
            arc = PoolManager.Instance.get(this.ArcPrefab);
        }
        const targetPos: Vec3 = new Vec3(this.CententPos.x + this.CircleRadius * vector.x, this.CententPos.y + this.CircleRadius * vector.y, this.CententPos.z);
        arc.getComponent(DrawingArc).init(this.node, targetPos, this.CircleRadius, this.Width, this.Angle, color);
        this._arcs.push(arc);
        // this.createItem(targetPos);
        this.addItem(targetPos);
    }

    getDis(other: Node): number {
        return Vec3.distance(this.BlackHole.getWorldPosition(), other.getWorldPosition());
    }

    getDir(other: Node): Vec3 {
        return this.BlackHole.getWorldPosition().subtract(other.getWorldPosition()).normalize();
    }

    private pause() {
        this._isPause = !this._isPause;
    }

    protected onEnable(): void {
        EventManager.on(MyEvent.PAUSE, this.pause, this);
    }

    protected onDisable(): void {
        EventManager.off(MyEvent.PAUSE, this.pause, this);
    }

    onTouchStart(event: EventTouch) {
        this._touchStart = event.getUILocation();
    }

    onTouchEnd(event: EventTouch) {
        // this._touchStart = event.getUILocation();
        const parce: Vec2 = event.getUILocation().subtract(this._touchStart).normalize().multiplyScalar(2);
        this.BlackHole.getComponent(BlackHole).velocity = parce;
        this.AredNode.active = false;
        this.IsStart = true;
    }

}


